package com.mdd.admin.service.bill.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mdd.admin.service.bill.OrderBillInfoService;
import com.mdd.admin.validate.bill.OrderBillInfoSearchValidate;
import com.mdd.common.base.page.PageValidate;
import com.mdd.common.core.PageResult;
import com.mdd.common.entity.OrderBillInfo;
import com.mdd.common.enums.ExpenseTypeEnum;
import com.mdd.common.enums.bill.BillTypeEnum;
import com.mdd.common.enums.order.status.LeaseOrderStatusEnum;
import com.mdd.common.mapper.bill.OrderBillInfoMapper;
import com.mdd.system.vo.SystemAuthAdminInformVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author DELL
 * @description 针对表【order_bill_info(账单信息)】的数据库操作Service实现
 * @createDate 2023-11-14 15:11:48
 */
@Slf4j
@Service
public class OrderBillInfoServiceImpl extends ServiceImpl<OrderBillInfoMapper, OrderBillInfo>
        implements OrderBillInfoService {


    /**
     * @param status 账单状态
     * @return 账单列表
     */
    @Override
    public List<OrderBillInfo> getRepaidPlan(Integer status) {
        LambdaQueryWrapper<OrderBillInfo> orderBillInfoWrapper = new LambdaQueryWrapper<>();
        //1、驳回待修改 2、待提交审核 3、审核中 4、待缴纳 5、已逾期 6、待激活 7、已支付 8、已取消
        orderBillInfoWrapper.eq(OrderBillInfo::getStatus, status);
        LocalDate nowDay = LocalDate.now();
        orderBillInfoWrapper.le(OrderBillInfo::getRepaymentStartDate, nowDay)
                .ge(OrderBillInfo::getRepaymentEndDate, nowDay);
        return this.baseMapper.selectList(orderBillInfoWrapper);
    }

    @Override
    public PageResult<OrderBillInfo> list(PageValidate pageValidate, OrderBillInfoSearchValidate orderBillInfoSearchValidate, SystemAuthAdminInformVo systemAuthAdmin) {
        Integer page  = pageValidate.getPageNo();
        Integer limit = pageValidate.getPageSize();
        LambdaQueryWrapper<OrderBillInfo> orderBillInfo=new LambdaQueryWrapper<>();
        if (!Objects.isNull(orderBillInfoSearchValidate.getStatus())) {
            orderBillInfo.eq(OrderBillInfo::getStatus, orderBillInfoSearchValidate.getStatus());
        }
        if (!Objects.isNull(orderBillInfoSearchValidate.getOrderId())) {
            orderBillInfo.eq(OrderBillInfo::getOrderId, orderBillInfoSearchValidate.getOrderId());
        }
        if (!Objects.isNull(orderBillInfoSearchValidate.getType())) {
            orderBillInfo.eq(OrderBillInfo::getExpenseCategoryId, orderBillInfoSearchValidate.getType());
        }
        if (!Objects.isNull(orderBillInfoSearchValidate.getExpenseCategoryId())) {
            orderBillInfo.eq(OrderBillInfo::getExpenseCategoryId, orderBillInfoSearchValidate.getExpenseCategoryId());
        }
        if (!systemAuthAdmin.getDeptIds().equals(1L)) {
            orderBillInfo.eq(OrderBillInfo::getMerchantId, systemAuthAdmin.getDeptIds());
        }
        Page<OrderBillInfo> iPage = this.baseMapper.selectPage(new Page<>(page, limit), orderBillInfo);
        return PageResult.iPageHandle(iPage.getTotal(), iPage.getCurrent(), iPage.getSize(), iPage.getRecords());
    }


    /**
     * 根据订单获取所有相关账单
     * @param orderId 订单编号
     * @return 账单列表
     */
    @Override
    public List<OrderBillInfo> getList(Long orderId) {
        LambdaQueryWrapper<OrderBillInfo> orderBillInfoWrapper = new LambdaQueryWrapper<>();
        orderBillInfoWrapper.eq(OrderBillInfo::getOrderId, orderId);
        return this.list(orderBillInfoWrapper);
    }
    @Transactional
    @Override
    public void cancelBill(Long orderId) {
        LambdaQueryWrapper<OrderBillInfo> orderBillInfoWrapper = new LambdaQueryWrapper<>();
        orderBillInfoWrapper.eq(OrderBillInfo::getOrderId, orderId);
        this.list(orderBillInfoWrapper).forEach(orderBillInfo -> {
            orderBillInfo.setStatus(LeaseOrderStatusEnum.CANCELED.getCode());
            updateById(orderBillInfo);
        });
    }
    @Transactional
    @Override
    public void createBillInfo(Long orderId, Long merchantId, Long userId, BigDecimal totalReceivables, Integer periods) {
        DateTime dateTime = DateUtil.beginOfDay(new Date());
        Instant instant = dateTime.toInstant();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
        //从第二天零点开始计费
        localDateTime = localDateTime.plusDays(1);
        LocalDateTime startLocalDateTime = null;
        List<OrderBillInfo> orderBillInfos = new ArrayList<>();
        for (int i = 0; i < periods; i++) {
            OrderBillInfo orderBillInfo = new OrderBillInfo();
            String name = "第" + (i + 1) + "期租赁账单";
            log.info("------------" + name + "----------------------------------------");
            orderBillInfo.setName(name);
            orderBillInfo.setCurrentPeriod(i+1);
            if (i == 0) {
                startLocalDateTime = localDateTime.plusMonths(i);
            }
            orderBillInfo.setMerchantId(merchantId);
            orderBillInfo.setOrderId(orderId);
            orderBillInfo.setUserId(userId);
            orderBillInfo.setTotalReceivables(totalReceivables);

            orderBillInfo.setExpenseTypeId(ExpenseTypeEnum.EXPENSE_TYPE_INCOME.getCode());
            orderBillInfo.setExpenseCategoryId(BillTypeEnum.RENT_BILL.getCode());

            ZonedDateTime startZonedDateTime = startLocalDateTime.atZone(ZoneId.systemDefault());
            Instant startInstant = startZonedDateTime.toInstant();
            Date startDate = DateUtil.beginOfDay(Date.from(startInstant));

            orderBillInfo.setRepaymentStartDate(startDate);

            String startTime = DateUtil.format(startDate, DatePattern.NORM_DATETIME_PATTERN);
            log.info("还款开始时间：" + startTime);
            //计算下一个月还款时间
            LocalDateTime endLocalDateTime = localDateTime.plusMonths(i + 1);
            ZonedDateTime endZonedDateTime = endLocalDateTime.atZone(ZoneId.systemDefault());
            Instant endInstant = endZonedDateTime.toInstant();
            Date endDate = DateUtil.endOfDay(Date.from(endInstant));

            orderBillInfo.setRepaymentEndDate(endDate);
            orderBillInfo.setStatus(LeaseOrderStatusEnum.TO_BE_ACTIVATED.getCode());

            String endTime = DateUtil.format(endDate, DatePattern.NORM_DATETIME_PATTERN);
            log.info("还款结束时间：" + endTime);
            startLocalDateTime = endLocalDateTime;
            orderBillInfos.add(orderBillInfo);
        }
        //保存账单信息
        saveBatch(orderBillInfos);
    }
    @Transactional
    @Override
    public void createBillInfo(Long orderId, Long merchantId, Long userId, BigDecimal totalReceivables, String name, Integer status,Integer categoryId) {
        OrderBillInfo orderBillInfo = new OrderBillInfo();
        orderBillInfo.setName(name);
        orderBillInfo.setMerchantId(merchantId);
        orderBillInfo.setOrderId(orderId);
        orderBillInfo.setUserId(userId);
        orderBillInfo.setTotalReceivables(totalReceivables);

        orderBillInfo.setExpenseTypeId(ExpenseTypeEnum.EXPENSE_TYPE_INCOME.getCode());
        orderBillInfo.setExpenseCategoryId(BillTypeEnum.PENALTY_BILL.getCode());
        Date startDate = DateUtil.beginOfDay(DateUtil.date());
        orderBillInfo.setRepaymentStartDate(startDate);
        String startTime = DateUtil.format(startDate, DatePattern.NORM_DATETIME_PATTERN);
        log.info("还款开始时间：" + startTime);
        //计算下一个月还款时间
        Date endDate = DateUtil.endOfDay(DateUtil.date());
        orderBillInfo.setRepaymentEndDate(endDate);
        orderBillInfo.setStatus(status);
        orderBillInfo.setExpenseCategoryId(categoryId);
        save(orderBillInfo);
    }


}




